package com.bdq.user.application.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.bdq.common.config.common.TokenInterceptor;
import com.bdq.common.entity.UserContext;
import com.bdq.common.entity.common.PageResult;
import com.bdq.common.enums.FollowTypeEnum;
import com.bdq.common.enums.UserContentTypeEnum;
import com.bdq.common.enums.YesOrNoEnum;
import com.bdq.common.exception.ServerException;
import com.bdq.common.exception.ServiceException;
import com.bdq.common.feign.content.param.UserPostPageParam;
import com.bdq.common.feign.content.vo.ContentListVO;
import com.bdq.common.feign.interaction.param.UserInteractionPageParam;
import com.bdq.common.utils.StaticFileUtil;
import com.bdq.common.utils.UserContextUtil;
import com.bdq.user.application.model.dto.*;
import com.bdq.user.application.model.query.ListFollowUserQry;
import com.bdq.user.application.model.query.UserContentPageQry;
import com.bdq.user.application.model.query.UserGetQry;
import com.bdq.user.application.service.MyFeignClient;
import com.bdq.user.application.service.UserAppQueryService;
import com.bdq.user.domain.model.agg.UserAgg;
import com.bdq.user.domain.model.dto.UserDomainDTO;
import com.bdq.user.domain.model.dto.UserFollowNumDomainDTO;
import com.bdq.user.domain.model.dto.ViewRegionLevelDomainDTO;
import com.bdq.user.domain.service.UserDomainService;
import com.bdq.user.infrastructure.persistence.mysql.pojo.User;
import com.bdq.user.infrastructure.persistence.mysql.pojo.UserFollow;
import com.bdq.user.infrastructure.persistence.mysql.service.UserFollowService;
import com.bdq.user.infrastructure.persistence.mysql.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author malei
 * @date 2024-05-03 17:17
 */
@Service
public class UserAppQueryServiceImpl implements UserAppQueryService {

    @Resource
    private UserDomainService userDomainService;

    @Resource
    private UserService userService;

    @Resource
    private UserFollowService userFollowService;

    @Resource
    private MyFeignClient myFeignClient;

    @Override
    public UserAppDTO userDetail() {
        // 1 获取用户信息
        UserContext userContext = UserContextUtil.getLoginUserContext(TokenInterceptor.getToken());

        // 2 用户聚合
        UserAgg userAgg = new UserAgg();
        userDomainService.userAggFill(userContext.getUserMobile(), userAgg);

        // 3 用户信息
        UserDomainDTO userDomainDTO = userDomainService.userDetail(userAgg);

        // 4 关注数量
        UserAppDTO userAppDTO = Convert.convert(UserAppDTO.class, userDomainDTO);
        UserFollowNumDomainDTO userFollowNumDomainDTO = userDomainService.userFollowNumGet(userContext.getId());
        BeanUtils.copyProperties(userFollowNumDomainDTO, userAppDTO);
        return userAppDTO;
    }

    @Override
    public UserQueryAppDTO userQuery(Long userId) {
        // 0 获取用户信息
        UserContext userContext = UserContextUtil.getLoginUserContext(TokenInterceptor.getToken());

        // 1 查询用户信息
        User user = userService.getById(userId);

        // 2 用户聚合
        UserAgg userAgg = new UserAgg();
        userDomainService.userAggFill(user.getUserMobile(), userAgg);

        // 3 用户信息
        UserDomainDTO userDomainDTO = userDomainService.userDetail(userAgg);
        UserQueryAppDTO userQueryAppDTO = Convert.convert(UserQueryAppDTO.class, userDomainDTO);

        // 4 关注数量
        UserFollowNumDomainDTO userFollowNumDomainDTO = userDomainService.userFollowNumGet(userId);
        BeanUtils.copyProperties(userFollowNumDomainDTO, userQueryAppDTO);

        // 5 是否关注
        UserFollow userFollow = userFollowService.get(userContext.getId(), userId);
        if (Objects.nonNull(userFollow)) {
            userQueryAppDTO.setIsFollowContentUser(YesOrNoEnum.YES.getCode());
        }
        return userQueryAppDTO;
    }

    @Override
    public List<ViewRegionLevelDTO> getViewRegionLevel() {
        // 1 获取用户信息
        UserContext userContext = UserContextUtil.getLoginUserContext(TokenInterceptor.getToken());

        // 2 用户聚合
        UserAgg userAgg = new UserAgg();
        userDomainService.userAggFill(userContext.getUserMobile(), userAgg);

        // 3 浏览区域信息
        List<ViewRegionLevelDomainDTO> domainDTOList = userDomainService.getViewRegionLevel(userAgg);
        return Convert.toList(ViewRegionLevelDTO.class, domainDTOList);
    }

    @Override
    public UserGetAppDTO getUser(UserGetQry qry) {
        User user = userService.getById(qry.getUserId());
        return Convert.convert(UserGetAppDTO.class, user);
    }

    @Override
    public List<UserListAppDTO> listUser(List<Long> userIds) {
        // 1 校验
        if (CollUtil.isEmpty(userIds)) {
            return Collections.emptyList();
        }

        // 2 查询
        List<User> userList = userService.list(userIds);
        return Convert.toList(UserListAppDTO.class, userList);
    }

    @Override
    public PageResult<ContentListVO> contentPage(UserContentPageQry qry) {
        // 1 获取用户信息
        UserContext userContext = UserContextUtil.getLoginUserContext(TokenInterceptor.getToken());

        // 2 检索内容ID
        PageResult<Long> pageResult;
        if (UserContentTypeEnum.PUBLISH.getCode() == qry.getType()) {
            // 2.1 用户发布内容
            UserPostPageParam userPostQueryParam = Convert.convert(UserPostPageParam.class, qry);
            pageResult = myFeignClient.pageUserPost(userPostQueryParam);
        }else {
            // 2.1 用户交互内容
            UserInteractionPageParam userInteractionPageParam = Convert.convert(UserInteractionPageParam.class, qry);
            pageResult = myFeignClient.pageUserInteraction(userInteractionPageParam);
        }

        // 3 内容
        if (CollUtil.isEmpty(pageResult.getList())) {
            return PageResult.empty(pageResult.getTotal());
        }
        List<ContentListVO> contentListVOS = myFeignClient.listContent(userContext.getId(), pageResult.getList());
        return new PageResult<>(contentListVOS, pageResult.getTotal());
    }

    @Override
    public List<UserFollowAppDTO> listUserFollow(Long followerUserId, List<Long> followedUserIds) {
        if (Objects.isNull(followerUserId) || CollUtil.isEmpty(followedUserIds)) {
            return Collections.emptyList();
        }
        List<UserFollow> userFollowList = userFollowService.list(followerUserId, followedUserIds);
        return Convert.toList(UserFollowAppDTO.class, userFollowList);
    }

    @Override
    public Boolean follow(Long userId) {
        UserContext userContext = UserContextUtil.getLoginUserContext(TokenInterceptor.getToken());
        try {
            if (userContext.getId() == userId) {
                throw new ServerException("关注人与被关注人不能是同一个人");
            }
            UserFollow userFollow = new UserFollow();
            userFollow.setFollowerUserId(userContext.getId());
            userFollow.setFollowedUserId(userId);
            userFollowService.save(userFollow);
        }catch (ServerException e) {
            throw e;
        }catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    @Override
    public Boolean cancelFollow(Long userId) {
        UserContext userContext = UserContextUtil.getLoginUserContext(TokenInterceptor.getToken());
        UserFollow userFollow = userFollowService.get(userContext.getId(), userId);
        if (Objects.nonNull(userFollow)) {
            userFollowService.removeById(userFollow);
        }
        return true;
    }

    @Override
    public PageResult<UserSimpleAppDTO> listFollow(ListFollowUserQry qry) {
        UserContext userContext = UserContextUtil.getLoginUserContext(TokenInterceptor.getToken());
        IPage<UserFollow> page;
        List<Long> userIds;
        if (qry.getType() == FollowTypeEnum.FOLLOWER.getCode()) {
            page = userFollowService.pageFollower(userContext.getId(), qry.getPageNo(), qry.getPageSize());
            userIds = page.getRecords().stream().map(UserFollow::getFollowedUserId).collect(Collectors.toList());
        }else if (qry.getType() == FollowTypeEnum.FOLLOWEE.getCode()) {
            page = userFollowService.pageFollowed(userContext.getId(), qry.getPageNo(), qry.getPageSize());
            userIds = page.getRecords().stream().map(UserFollow::getFollowerUserId).collect(Collectors.toList());
        }else {
            page = userFollowService.pageEachFollower(userContext.getId(), qry.getPageNo(), qry.getPageSize());
            userIds = page.getRecords().stream().map(UserFollow::getFollowedUserId).collect(Collectors.toList());
        }
        if (CollUtil.isEmpty(page.getRecords())) {
            return PageResult.empty(page.getTotal());
        }

        List<User> userList = userService.list(userIds);
        for (User user : userList) {
            user.setAvatar(StaticFileUtil.domainConcat(user.getAvatar()));
        }
        return new PageResult<>(Convert.toList(UserSimpleAppDTO.class, userList), page.getTotal());
    }
}
